package com.corn.juc.lock.custome;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author : Jim Wu
 * @version 1.0
 * @function :
 * @since : 2020/12/30 17:06
 */

public class SpinReadWriteLockTest {

    public static void main(String[] args) {
        safeDemo();
    }

    public static void safeDemo() {
        ShareData shareData = new ShareData();
        SpinReadWriteLock lock = new SpinReadWriteLock();
        for (int i = 0; i < 5; i++) {
            final int temp = i;
            new Thread() {
                @Override
                public void run() {
                    try {
                        lock.writeLock();
                        shareData.put(String.valueOf(temp), temp);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        lock.writeUnlock();
                    }
                }
            }.start();
        }

        for (int i = 0; i < 5; i++) {
            final int temp = i;
            new Thread() {
                @Override
                public void run() {
                    try {
                        lock.readLock();
                        System.out.println(shareData.get(String.valueOf(temp)));
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        lock.readUnlock();
                    }
                }
            }.start();
        }

    }

}

class ShareData2 {
    private volatile Map<String, Object> data = new HashMap<>();

    public void put(String key, Object value) {
        System.out.println(Thread.currentThread().getName() + "\t写入操作...");
        // 模拟耗时操作
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        data.put(key, value);
        System.out.println(Thread.currentThread().getName() + "\t写入完成...");

    }

    public Object get(String key) {
        System.out.println(Thread.currentThread().getName() + "\t读取操作...");
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Object result = data.get(key);
        System.out.println(Thread.currentThread().getName() + "\t读取完成...");
        return result;
    }

}
